﻿using System.Collections.Generic;
using Microsoft.Data.Schema.ScriptDom.Sql;
using System.IO;
using System.Text.RegularExpressions;


namespace Neznayka
{
    internal class CLRWrapperVisitor : TSqlConcreteFragmentVisitor
    {
        private List<ProcedureStatementBodyBase> _targets;

        #region ctor
        public CLRWrapperVisitor()
        {
            _targets = new List<ProcedureStatementBodyBase>();
        }
        #endregion

        #region properties
        public List<ProcedureStatementBodyBase> CLRWrappers
        {
            get { return _targets; }
        }
        #endregion

        #region overrides
        public override void ExplicitVisit(AlterFunctionStatement node)
        {
            bool foundExternalName = CheckText(node);
            if (foundExternalName)
            {
                _targets.Add(node);
            }
        }
        public override void ExplicitVisit(CreateFunctionStatement node)
        {
            bool foundExternalName = CheckText(node);
            if (foundExternalName)
            {
                _targets.Add(node);
            }
        }
        public override void ExplicitVisit(AlterProcedureStatement node)
        {
            bool foundExternalName = CheckText(node);
            if (foundExternalName)
            {
                _targets.Add(node);
            }
        }
        public override void ExplicitVisit(CreateProcedureStatement node)
        {
            bool foundExternalName = CheckText(node);
            if (foundExternalName)
            {
                _targets.Add(node);
            }
        }
        #endregion

        private static bool CheckText(TSqlFragment node)
        {
            bool foundExternalName = false;
            for (int i = node.FirstTokenIndex; !foundExternalName && (i <= node.LastTokenIndex - 2); i++)
            {
                //using (StreamWriter w = File.AppendText(@"c:\temp\CheckText.txt"))
                //{
                //    w.WriteLine(@"["+node.ScriptTokenStream[i].Text+@"]");
                //    w.Close();
                //}

                int next_i = i;
                if (Regex.IsMatch(node.ScriptTokenStream[next_i].Text, @"^\s*AS\s*$", RegexOptions.IgnoreCase & RegexOptions.Multiline & RegexOptions.Singleline))
                {
                    next_i++;
                    while (next_i <= node.LastTokenIndex && Regex.IsMatch(node.ScriptTokenStream[next_i].Text, @"^\s*$", RegexOptions.IgnoreCase & RegexOptions.Multiline & RegexOptions.Singleline)) { next_i++; }
                    if (next_i <= node.LastTokenIndex) {
                        if (Regex.IsMatch(node.ScriptTokenStream[next_i].Text, @"^\s*EXTERNAL\s*$", RegexOptions.IgnoreCase & RegexOptions.Multiline & RegexOptions.Singleline))
                        {
                            next_i++;
                            while (next_i <= node.LastTokenIndex && Regex.IsMatch(node.ScriptTokenStream[next_i].Text, @"^\s*$", RegexOptions.IgnoreCase & RegexOptions.Multiline & RegexOptions.Singleline)) { next_i++; }
                            if (next_i <= node.LastTokenIndex) {
                                if (Regex.IsMatch(node.ScriptTokenStream[next_i].Text, @"^\s*NAME\s*$", RegexOptions.IgnoreCase & RegexOptions.Multiline & RegexOptions.Singleline))
                                {
                                    foundExternalName = true;
                                }
                            }
                        }
                    }
                }
            }
            return foundExternalName;
        }
    }


}